﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RPGXEngine
{
    public class AssignmentCommand_Equals : IAssignmentCommand
    {
        #region IAssignmentCommand Members

        public ICommand Left { get; set; }
        public ICommand Right { get; set; }

        #endregion

        #region ICommand Members

        public bool IsReturn { get { return false; } }
        public bool IsIf { get { return false; } }

        public List<ICommand> ChildrenCommands
        {
            get
            {
                return null;
            }
        }

        public IVariableType Execute(ScriptManager sm, FunctionScope scope)
        {
            // it seems that if we do something like this:
            // array a;
            // a = [1,2,3,4];
            // a[0] = a[1]
            // then v1 above will equal v2 because the variables are technically the same instance
            // so this is a work around for that - maybe in version 2 of this scripting language, arrays can be designed
            // so this work around is not needed
            if (this.Left is Command_Variable &&
                this.Right is Command_Variable)
            {
                IVariableType ordinal1 = null;
                IVariableType ordinal2 = null;

                IVariableType v1 = this.Left.Execute(sm, scope);

                if (v1.Type == DataType.Array)
                {
                    ordinal1 = ((ArrayVariableType)v1).ArrayOrdinal;
                }

                IVariableType v2 = this.Right.Execute(sm, scope);

                if (v2.Type == DataType.Array)
                {
                    ordinal2 = ((ArrayVariableType)v2).ArrayOrdinal;
                }

                if (ordinal1 != null && ordinal2 != null &&
                    v1.Name == v2.Name)
                {
                    ((ArrayVariableType)v1).SetOrdinalValue(ordinal1, ordinal2);
                }
                else
                {
                    v1.SetValue(v2);
                }

                return v1;
            }
            else
            {
                IVariableType v1 = this.Left.Execute(sm, scope);
                IVariableType v2 = this.Right.Execute(sm, scope);

                v1.SetValue(v2);

                return v1;
            }
        }

        #endregion
    }
}
